package com.imoresoft.agile.action;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.json.annotations.JSON;

import com.ambitor.grass.util.data.DataMap;
import com.ambitor.grass.util.data.DatasetList;
import com.ambitor.grass.util.data.IData;
import com.ambitor.grass.util.data.IDataset;
import com.imoresoft.agile.property.AppConstants;
import com.imoresoft.agile.property.SessionConstants;
import com.imoresoft.agile.top.TopConstants;
import com.imoresoft.agile.top.TopService;
import com.imoresoft.agile.view.Pager;
import com.imoresoft.magic.util.DateUtil;
import com.taobao.api.domain.Item;

public class ItemAction extends JsonBaseAction {

	private transient String searchKey;

	private transient boolean refresh = false;

	private transient String sellerCids;
	
	private transient String iids = null;
	private static transient Map<Long, IData> itemMap = new HashMap<Long, IData>();

	private transient String approveStatus = "onSale";

	private transient static final long serialVersionUID = -4007353262928075395L;

	private transient TopService topService = null;
	
	public ItemAction() {
		topService = new TopService(TopConstants.EVN_SWITCH,
				TopConstants.APP_KEY, TopConstants.APP_SECRET);
	}

	public void setSearchKey(String searchKey)
			throws UnsupportedEncodingException {
		this.searchKey = URLDecoder.decode(searchKey,
				AppConstants.APPLICATION_ENCODING);
	}

	@JSON(serialize = false)
	public String getSearchKey() {
		return searchKey;
	}

	@JSON(serialize = false)
	public String getSellerCids() {
		return sellerCids;
	}
	
	@JSON(serialize = false)
	public String getIids() {
		return iids;
	}

	public void setIids(String iids) {
		this.iids = StringUtils.trimToEmpty(iids);
	}

	public void setSellerCids(String cid) {
		this.sellerCids = cid;
	}

	public void setRefresh(boolean refresh) {
		this.refresh = refresh;
	}

	public String getApproveStatus() {
		return approveStatus;
	}

	public void setApproveStatus(String approveStatus) {
		this.approveStatus = approveStatus;
	}

	@JSON(serialize = false)
	public boolean isRefresh() {
		return refresh;
	}

	@Override
	public Pager getPager() {
		return pager;
	}

	@Override
	@SuppressWarnings("unchecked")
	public IDataset getDataset() {
		return dataset;
	}

	@SuppressWarnings("unchecked")
	public String queryItems() throws Exception {
		
		if (pager.getCurPageNo() != 1)
			refresh = false; // 同步数据的请求curpageno一定是1，否则不同步，为解决jqgrid的问题而加

		IDataset items = null;
		if ("inventory".equals(this.getApproveStatus())) {
			items = queryInventoryItems(refresh);
		} else {
			items = queryOnSaleItems(refresh);
		}

		items = filterBySearchKey(items);
		items = filterBySellerCat(items);
		pager.setTotalCount(items.size());
		try {
			dataset.addAll(items.subList(pager.getFirst(), pager.getEnd()));
		} catch(Exception e) {
			logger.error("", e);
		}
		logger.info("共" + pager.getTotalCount() + "条记录");
		logger.info("共" + pager.getTotalPages() + "页");
		logger.info("当前请求的是第" + pager.getCurPageNo() + "页");
		logger.info("从过滤后的结果集中取出从" + (pager.getFirst() + 1) + "到"
				+ pager.getEnd() + "共" + dataset.count() + "条记录.");
		sort();
		logger.info("返回排序后的最终结果.");
		
		return SUCCESS;
	}

	private IDataset queryOnSaleItems(boolean refresh) throws Exception {
		logger.info("queryOnsaleItems() starting...");
		Object object = pd
				.getSessionAttribute(SessionConstants.SESSEION_ONSALE_ITEMS);
		IDataset onSaleItems = new DatasetList();
		if (object == null || refresh == true) {
			TopService topService = new TopService(TopConstants.EVN_SWITCH,
					TopConstants.APP_KEY, TopConstants.APP_SECRET);
			String sessionId = pd.getTopSessionId();
			String nick = pd.getTopNick();
			onSaleItems = itemsListToIDataset(topService.getOnSaleItems(
					sessionId, nick));

			pd.setSessionAttribute(SessionConstants.SESSEION_ONSALE_ITEMS,
					onSaleItems);
			logger.info("queryOnSaleItems取出" + onSaleItems.size()
					+ "条数据放到了session中");
		} else {
			onSaleItems = (IDataset) object;
			logger.info("从session中取出" + onSaleItems.count() + "条记录.");
		}
		return onSaleItems;
	}

	private IDataset queryInventoryItems(boolean refresh) throws Exception {
		Object object = pd
				.getSessionAttribute(SessionConstants.SESSEION_INVENTORY_ITEMS);
		IDataset inventoryItems = new DatasetList();
		if (object == null || refresh == true) {
			String sessionId = pd.getTopSessionId();
			String nick = pd.getTopNick();
			inventoryItems = itemsListToIDataset(topService.getInventoryItems(
					sessionId, nick));
			pd.setSessionAttribute(SessionConstants.SESSEION_INVENTORY_ITEMS,
					inventoryItems);
		} else {
			inventoryItems = (IDataset) object;
		}
		return inventoryItems;
	}

	private void sort() {
		if (dataset == null || dataset.size() == 1) {
			logger.info("结果集为空或只有一条，无需排序");
			return;
		}
		int order = IDataset.ORDER_ASCEND;
		int order_type = IDataset.TYPE_STRING;
		if (pager.getOrder() == null || pager.getOrderBy() == null) {
			return;
		}
		if (AppConstants.PAGER_DESC.equals(pager.getOrder())) {
			order = IDataset.ORDER_DESCEND;
		}
		if (pager.getOrderBy().equalsIgnoreCase("price")) {
			order_type = IDataset.TYPE_DOUBLE;
		}
		dataset.sort(pager.getOrderBy(), order_type, order);
		logger.info("对" + pager.getOrderBy() + "进行" + pager.getOrder() + "排序");
	}

	private IDataset filterBySearchKey(IDataset allItemsOnSale)
			throws Exception {
		logger.info("开始根据searchKey过滤查询出的结果集");
		if (searchKey == null) {
			logger.info("searchKey==null，停止过滤");
			return allItemsOnSale;
		}
		searchKey = searchKey.trim();
		if (searchKey.equals("")) {
			logger.info("searchKey为空，停止过滤");
			return allItemsOnSale;
		}
		String filterStr = buildFilterStr(searchKey, new String[] { "title" },
				false);
		logger.info("拼出的filter串是" + filterStr);
		IDataset itemOnSaleFiltered = allItemsOnSale.filter(filterStr);

		logger.info("根据关键字共过滤到符合条件的结果" + itemOnSaleFiltered.count() + "条");
		return itemOnSaleFiltered;
	}

	private IDataset filterBySellerCat(IDataset items) throws Exception {
		logger.info("开始根据SellerCat过滤查询出的结果集");
		if (sellerCids == null) {
			logger.info("sellerCids==null，停止过滤");
			return items;
		}
		sellerCids = sellerCids.trim();
		if ("".equals(sellerCids) || sellerCids.equals("all_cats")) {
			logger.info("sellerCids为空或者sellerCids='all_cats'，停止过滤");
			return items;
		}
		String filterStr = "seller_cids~" + sellerCids;
		IDataset itemsFiltered = items.filter(filterStr);
		logger.info("根据sellerCids共过滤到符合条件的结果" + itemsFiltered.count() + "条");
		return itemsFiltered;
	}

	@SuppressWarnings("unchecked")
	private IDataset itemsListToIDataset(List<Item> items) {
		IDataset dataset = new DatasetList();
		if (items == null || items.size() <= 0)
			return dataset;
		for (Item item : items) {
			IData data = new DataMap();
			data.put("iid", item.getNumIid());
			data.put("num", item.getNum());
			data.put("title", item.getTitle());// jqgrid显示的时候做处理
			data.put("frank_title", item.getTitle());// tilte的本来面目
			data.put("price", item.getPrice());
			data.put("pic_url", item.getPicUrl());
			data.put("delist_time", DateUtil.formatDate(item.getDelistTime()));
			data.put("seller_cids", item.getSellerCids());
			data.put("approve_status", item.getApproveStatus());
			dataset.add(data);
			itemMap.put(item.getNumIid(), data);
		}
		return dataset;
	}

	private String buildFilterStr(String searchKey, String[] keys,
			boolean precise) {
		if (searchKey == null || keys == null || searchKey.trim().equals("")
				|| keys.length == 0)
			return "";
		String[] searchKeys = searchKey.split("[\\s]+");
		String symbol = "~";
		if (precise)
			symbol = "=";

		StringBuilder filterStr = new StringBuilder();
		for (String str : searchKeys) {
			for (String key : keys)
				filterStr.append(key + symbol + str + ";");
		}
		filterStr.deleteCharAt(filterStr.lastIndexOf(";"));
		return filterStr.toString();
	}
}
